/**
 * Licensed to the Rivulet under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *     webapps/LICENSE-Rivulet-1.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.rivues.task.resource;

import java.io.IOException;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Statement;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Restrictions;
import org.rivu.tools.ParamTools;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.rivues.core.RivuDataContext;
import com.rivues.module.datamodel.web.handler.DefaultParam;
import com.rivues.module.datamodel.web.handler.DefaultValue;
import com.rivues.module.platform.web.bean.TaskInfo;
import com.rivues.module.platform.web.model.Cube;
import com.rivues.module.platform.web.model.CubeMetadata;
import com.rivues.module.platform.web.model.Database;
import com.rivues.module.platform.web.model.JobDetail;
import com.rivues.module.platform.web.model.PublishedCube;
import com.rivues.module.platform.web.model.TableProperties;
import com.rivues.module.platform.web.model.TableTask;
import com.rivues.util.RivuTools;
import com.rivues.util.data.DatabaseMetaDataHandler;
import com.rivues.util.datasource.DataSourceTools;
import com.rivues.util.iface.cube.CubeFactory;
import com.rivues.util.serialize.JSON;
import com.rivues.util.service.ServiceHelper;
import com.rivues.util.tools.H2Helper;
import com.rivues.util.tools.RivuColumnMetadata;
import com.rivues.util.tools.RivuTableMetaData;
import com.rivues.util.tools.TabelSql;

/**
 * @author jaddy0302 Rivulet TableResource.java 2010-4-11
 * 
 */
public class DatabaseResource extends Resource {
	
	private final Logger log = LoggerFactory.getLogger(DatabaseResource.class); 
	private JobDetail job ;
	private TabelSql tableSQL = null ;
	private Date updateDate = null ;
	private Properties properties = null ;
	private boolean incremental = false ;			//结算模式 ， 是否增量结算
	
	private TableTask source ;
	private TableTask target ;
	
	private Cube cube = null ;
	private PublishedCube publishedCube = null ;
	private DefaultParam defaultParam = null ;
	
	private void resetConnection(final TableTask task ) throws Exception{
		properties = ParamTools.getProperties(task.getDatabase().getConnectparam());
		task.setConn(DataSourceTools.createDataSource(task.getDatabase()).getConnection()) ;
	}
	/**
	 * 获取数据
	 * @param task
	 * @return
	 * @throws Exception
	 */
	private void getResultSet(TableTask task) throws Exception{
		//填充任务里面设置的参数
		if(job.getTaskinfo()!=null&&job.getTaskinfo().length()>0){
			TaskInfo taskinfo = JSON.parseObject(job.getTaskinfo(), TaskInfo.class);
			if(taskinfo.getParams()!=null&&taskinfo.getParams().length()>0){
				DefaultParam defaultParam = new DefaultParam();
				if(task.getPreviewtemplet()!=null && task.getPreviewtemplet().length()>0){
					defaultParam = JSON.parseObject(task.getPreviewtemplet(), DefaultParam.class) ;
				}
				String[] params = taskinfo.getParams().split(",");
				for (String string : params) {
					String[] param = string.split("=");
					if(param.length>=1){
						DefaultValue value = new DefaultValue(param[0], param[1], null);
						defaultParam.getValues().add(value);
					}
					
				}
				task.setPreviewtemplet(JSON.toJSONString(defaultParam));
				
			}
		}
		
		tableSQL = DatabaseMetaDataHandler.getSQL(properties,task , this.job.getStartindex() , 0) ;
		log.info("SQL:"+tableSQL.getSql()) ;
		task.setStatment(task.getConn().prepareStatement(tableSQL.getSql())) ;
		
		if(tableSQL.isParame()){ //never be run
			if( job.getStartindex()>0){
				task.getStatment().setInt(1, (int)job.getStartindex()) ;
				task.getStatment().setInt(2, 50000) ;
				if(tableSQL.getUpdatetime()!=null){
					task.getStatment().setDate(3, new java.sql.Date(task.getUpdatetime().getTime())) ;
				}
				
			}else{
				task.getStatment().setInt(1, 50000) ;
				if(tableSQL.getUpdatetime()!=null){
					task.getStatment().setDate(2, new java.sql.Date(task.getUpdatetime().getTime())) ;
				}
			}
		}else{
			if(tableSQL.getModitp()!=null){
				task.getStatment().setTimestamp(1, new java.sql.Timestamp((task.getLastupdate()!=null?task.getLastupdate():new Date(0L)).getTime())) ;
			}
			if(task.getUserid()!=null && task.getUserid().equals("1")){
				task.getStatment().setInt(1, (int)job.getStartindex()) ;
			}
		}
		task.setResultSet(task.getStatment().executeQuery());//DatabaseMetaDataHandler.getTableData(conn , statment , properties, task) ;
		if(properties.getProperty("num")==null && properties.getProperty("dialect")==null){
			if(tableSQL.getModitp()==null && job.getStartindex()>0){ // if change update by time to startindex , may be lost same data 
				for(int i=0 ; i<job.getStartindex() ; i++){
					task.getResultSet().next() ;
				}
			}
		}
	}
	/* (non-Javadoc)
	 * @see org.jaddy.rivu.resource.Resource#close()
	 */
	@SuppressWarnings("unchecked")
	public DatabaseResource(final JobDetail job) throws Exception{
		this.job = job ;
		publishedCube = (PublishedCube) RivuDataContext.getService().getIObjectByPK(PublishedCube.class, job.getTaskid()) ;
		if(publishedCube!=null){
			cube = publishedCube.getCube();
		}
		/**
		 * 初始化 ， 获取 TableTask
		 */
		if(cube!=null){
			initTableTask(this.job.getOrgi());
			for(CubeMetadata meta : cube.getMetadata()){
				if("0".equals(meta.getMtype()) || cube.getMetadata().size()==1){//设置为主表
					if(meta.getTb()!=null && meta.getTb().getPreviewtemplet()!=null && meta.getTb().getPreviewtemplet().length()>0){
						incremental = true ;
						defaultParam = JSON.parseObject(meta.getTb().getPreviewtemplet() , DefaultParam.class) ;
					}
				}
			}
		}
	}
	
	public void begin() throws Exception{
		if(this.source==null){
			if(this.target!=null){
				RivuDataContext.getService().deleteIObject(this.target) ;
			}
			this.createResource(this.job.getTaskid(), this.job.getOrgi()) ;
		}
		if(source!=null && source instanceof TableTask){
			if(this.defaultParam!=null){
				this.source.setPreviewtemplet(JSON.toJSONString(this.defaultParam)) ;
			}
			resetConnection(source);
			getResultSet(source);
		}
		if(this.cube!=null && this.cube.getDataflag()==null){
			this.cube.setDataflag("0") ;
		}
		if(target!=null){
			target.close();
			this.resetConnection(target) ;
		}
	}
	
	@SuppressWarnings("unchecked")
	@Override
	public void end(boolean clear) throws Exception {
		cube.setCreatedata("true") ;
		cube.setStartindex((int)job.getStartindex()) ;
		cube.setStartdate(new Date()) ;
		
		publishedCube.setCreatedata("publishedCube") ;
		publishedCube.setStartindex((int)job.getStartindex()) ;
		publishedCube.setStartdate(cube.getStartdate()) ;
		/**
		 * 更新 Schema文件，Only One Line
		 */
		try {
			/**
			 * 增量结算，需要删除以前版本的数据
			 */
			if(!this.incremental && clear){
				
				if(!this.incremental){
					cube.setDataflag(String.valueOf(Integer.parseInt(cube.getDataflag()!=null && cube.getDataflag().matches("[\\d]*")?cube.getDataflag():"0")+1)) ;
				}else{
					cube.setDataflag("0") ;
				}
				
				StringBuilder strb = new StringBuilder() ;
				String viewName = "C_D_"+com.rivues.util.RivuTools.md5(cube.getId()) ;
				String tableName = new StringBuffer().append(viewName.toUpperCase()).append("_VT").toString() ;
				strb.append("DROP VIEW ").append(viewName) ;
				H2Helper.executeSQL(strb.toString() , this.target.getDatabase() , false) ;
				strb = new StringBuilder() ;
				if(Integer.parseInt(cube.getDataflag())>=2){
					strb.append("CREATE VIEW ").append(viewName.toUpperCase()).append(" AS (SELECT * FROM ").append(tableName).append(" WHERE R3_CUBE_DATA_VERSION='").append(Integer.parseInt(cube.getDataflag())-1).append("')") ;
				}else{
					strb.append("CREATE VIEW ").append(viewName.toUpperCase()).append(" AS (SELECT * FROM ").append(tableName).append(" WHERE R3_CUBE_DATA_VERSION='0')") ;
				}
				H2Helper.executeSQL(strb.toString() , this.target.getDatabase()) ;
				
				strb = new StringBuilder();
				//一个etl任务完全执行完毕后  执行删除以前汇总数据的操作
				strb.append("DELETE FROM ").append(tableName).append(" WHERE R3_CUBE_DATA_VERSION  <> '"+(Integer.parseInt(cube.getDataflag())-1)+"'");
				H2Helper.executeSQL(strb.toString() , this.target.getDatabase()) ;
			}else{
				/**
				 * 增量结算表，需要更新 source的 Table Task
				 */
				
			}
		} catch (Exception e) {
			e.printStackTrace();
		}finally{
			this.close();
			if(publishedCube!=null){
				/**
				 * 更新数据库中Cube的版本
				 */
				publishedCube.setCubecontent(JSON.toJSONString(cube)) ;
				RivuDataContext.getService().updateIObject(publishedCube) ;
				List<Cube> cubeList = RivuDataContext.getService().findAllByCriteria(DetachedCriteria.forClass(Cube.class).add(Restrictions.eq("id", cube.getId())));
				if(cubeList!=null && cubeList.size()>0){
					Cube sourceCube = cubeList.get(0) ;
					sourceCube.setDataflag(cube.getDataflag()) ;
					sourceCube.setCreatedata(cube.getCreatedata()) ;
					sourceCube.setStartindex(cube.getStartindex()) ;
					sourceCube.setStartdate(cube.getStartdate()) ;
					RivuDataContext.getService().updateIObject(sourceCube) ;
				}
			}
		}
	}

	
	@SuppressWarnings("unchecked")
	public void createResource(Object data , String orgi) throws Exception{
		String sql;
		try{
			if(data!=null){
				this.source = new TableTask() ;
				this.source.setDatabase(ServiceHelper.getDatabaseService().getDatabase(this.cube.getDb())) ;
				this.source.setOrgi(orgi) ;
				this.source.setName(cube.getTable().toUpperCase());
				this.source.setGroupid(CubeFactory.getCubeInstance().getJobNameByCubeDic(cube.getTypeid(),cube.getOrgi())+"/"+cube.getName());
				this.source.setCode(cube.getTable().toUpperCase());
				this.source.setTabletype("2") ;
				this.source.setTabledirid("1") ;
				if(this.defaultParam!=null){
					this.source.setPreviewtemplet(JSON.toJSONString(defaultParam)) ;
					this.job.setClazz("1") ;//结算表，危险操作，删除将会导致数据不可用
				}
				this.source.setDatasql(sql = DatabaseMetaDataHandler.getCubeSQL(cube , orgi , this.source)) ;
				this.source.setDbid(this.cube.getDb()) ;
				this.source.setTablename(this.source.getName()) ;
				this.source.setUserpage(true) ;
				
				/**
				 * 
				 * 
				 */
				RivuTableMetaData tableMetaData = getTableTaskProperties(this.source , orgi);
				
				
				TableProperties tableProperty = new TableProperties("R3_CUBE_DATA_ID", "VARCHAR", 12, this.source.getName());
				DatabaseMetaDataHandler.addPropertiesOldName(cube, orgi, this.source);//把原始名称补充上去
				tableProperty.setPk(true);
				tableProperty.setGroupid("R3_CUBE_DATA_ID");
				tableProperty.setOrgi(orgi) ;
				this.source.getTableproperty().add(tableProperty) ;
				this.source.setDatasql(sql = DatabaseMetaDataHandler.getCubeSQL(cube , orgi , this.source)) ;
				/**
				 * VERSION
				 */
				tableProperty = new TableProperties("R3_CUBE_DATA_VERSION", "VARCHAR", 12, this.source.getName());
				tableProperty.setPk(true);
				tableProperty.setGroupid("R3_CUBE_DATA_VERSION");
				tableProperty.setOrgi(orgi) ;
				this.source.getTableproperty().add(tableProperty) ;
				RivuDataContext.getService().saveIObject(this.source) ;
				this.job.setCrawltask(this.source.getId()) ;
				
				Database database = null ;
				List<Database> databaseList = RivuDataContext.getService().findAllByCriteria(DetachedCriteria.forClass(Database.class).add(Restrictions.and(Restrictions.eq("orgi", orgi) , Restrictions.eq("name", "R3_SYSTEM")))) ;
				if(databaseList.size()>0){
					database = databaseList.get(0) ;
				}else{
					throw new Exception("请先创建一个名称为 R3_SYSTEM的数据库连接。");
				}
				String tableName = new StringBuffer().append(this.source.getName().toUpperCase()).append("_VT").toString() ;
				//先删除表，然后再创建
				StringBuffer strb = new StringBuffer() ;
				strb.append("DROP VIEW ").append(this.source.getName().toUpperCase());
				H2Helper.executeSQL(strb.toString() , database , false) ;	
				
				strb = new StringBuffer() ;
				strb.append("DROP TABLE ").append(tableName) ;
				H2Helper.executeSQL(strb.toString() , database , false) ;	
				String createSQL = DatabaseMetaDataHandler.getCreateSQL(tableMetaData,database);
				log.info(createSQL) ;
				
				
				H2Helper.executeSQL(createSQL , database) ;
				strb = new StringBuffer() ;
				strb.append("ALTER TABLE ").append(tableName).append(" ADD R3_CUBE_DATA_ID VARCHAR(32) NOT NULL") ;
				H2Helper.executeSQL(strb.toString() , database) ;	
				strb = new StringBuffer() ;
				strb.append("ALTER TABLE ").append(tableName).append(" ADD R3_CUBE_DATA_VERSION VARCHAR(32) NOT NULL") ;
				H2Helper.executeSQL(strb.toString() , database) ;	
				strb = new StringBuffer() ;
				strb.append("ALTER TABLE ").append(tableName).append(" ADD PRIMARY KEY(R3_CUBE_DATA_ID)") ;
				H2Helper.executeSQL(strb.toString() , database) ;	
				
				strb = new StringBuffer() ;
				strb.append("CREATE VIEW ").append(this.source.getName().toUpperCase()).append(" AS (SELECT * FROM ").append(tableName).append(" WHERE R3_CUBE_DATA_VERSION='0')") ;
				H2Helper.executeSQL(strb.toString() , database) ;
				
				//创建索引
				DatabaseMetaDataHandler.createDatabaseIndex(cube, orgi, this.source, database);
				
				{
					/**
					 * 将 表字段对象的ID设置为 null ， 否则后面保存对象会导致 前一个对象的字段被清空
					 */
					List<TableProperties> tpList = new ArrayList<TableProperties>();
					for(TableProperties tp : this.source.getTableproperty()){
						tp.setId(null) ;
						tp.setDbtableid(null);
						tpList.add(tp.clone()) ;
					}
					
					this.target = new TableTask() ;
					this.target.setDatabase(database) ;
					this.target.setOrgi(orgi) ;
					this.target.setName("C_D_"+com.rivues.util.RivuTools.md5(cube.getId()));
					this.target.setCode(this.source.getName());
					this.target.setGroupid(CubeFactory.getCubeInstance().getJobNameByCubeDic(cube.getTypeid(),cube.getOrgi())+"/"+cube.getName());
					this.target.setDatasql(sql) ;
					this.target.setTabletype("1") ;
					this.target.setTablename(this.source.getName()) ;
					this.target.setTableproperty(new HashSet<TableProperties>());
					this.target.setTabledirid("1") ;
					this.target.setDbid(database.getId()) ;
					
					this.target.getTableproperty().addAll(tpList) ;
					RivuDataContext.getService().saveIObject(this.target) ;
					this.job.setTargettask(this.target.getId()) ;
					
					
					/**
					 * 更新JobDetail
					 */
					RivuDataContext.getService().updateIObject(job) ;
				}
			}
		}catch(Exception ex){
			ex.printStackTrace() ;
			throw ex;
		}
	}
	@Override
	public void rmResource() {
		if(this.source!=null){
			RivuDataContext.getService().deleteIObject(this.source) ;
		}
		if(this.target!=null){
			String tableName = new StringBuffer().append(this.source.getName().toUpperCase()).append("_VT").toString() ;
			//先删除表，然后再创建
			StringBuffer strb = new StringBuffer() ;
			strb.append("DROP VIEW ").append(this.source.getName().toUpperCase());
			H2Helper.executeSQL(strb.toString() , this.target.getDatabase() , false) ;	
			
			strb = new StringBuffer() ;
			strb.append("DROP TABLE ").append(tableName) ;
			H2Helper.executeSQL(strb.toString() , this.target.getDatabase() , false) ;	
			
			RivuDataContext.getService().deleteIObject(this.target) ;
			
			/**
			 * 同时，需要将 Cube的 createdata设置为  false， 避免出现 删除结算表以后 模型无法使用的情况
			 */
			if(publishedCube!=null){
				publishedCube.setCreatedata(null) ;
				Cube cube = publishedCube.getCube() ;
				cube.setCreatedata(null) ;
				publishedCube.setCubecontent(JSON.toJSONString(cube)) ;
				Cube cb = CubeFactory.getCubeInstance().getCubeObjectByID(cube.getId());
				cb.setCreatedata("false");
				if(cb!=null)
					RivuDataContext.getService().updateIObject(cb);
				RivuDataContext.getService().updateIObject(publishedCube) ;
			}
		}
	}
	
	/**
	 * 初始化 结算表数据信息
	 */
	private void initTableTask(String orgi){
		List<TableTask> tableTaskList = RivuDataContext.getService().findAllByCriteria(DetachedCriteria.forClass(TableTask.class).add(Restrictions.and(Restrictions.eq("orgi", orgi) , Restrictions.eq("id", this.job.getCrawltask())))) ;
		if(tableTaskList.size()>0){
			this.source = tableTaskList.get(0) ;
		}
		tableTaskList = RivuDataContext.getService().findAllByCriteria(DetachedCriteria.forClass(TableTask.class).add(Restrictions.and(Restrictions.eq("orgi", orgi) , Restrictions.eq("id", this.job.getTargettask())))) ;
		if(tableTaskList.size()>0){
			this.target = tableTaskList.get(0) ;
		}
	}
	
	/**
	 * 
	 * @return
	 * @throws IOException
	 */
	public RivuTableMetaData getTableTaskProperties(TableTask data, String orgi) throws Exception {
		RivuTableMetaData tableMetaData = null;
		try {
			if (data.getTabletype().equals("1")) {
				tableMetaData = DatabaseMetaDataHandler.getTable(
						data.getDatabase(), data.getTablename());
			} else if (data.getTabletype().equals("2")) {
				String dataSQL = data.getFormatDatasql() ;
				if (dataSQL.toLowerCase().indexOf("select ") < 0
						|| dataSQL.toLowerCase().indexOf("update ") >= 0
						|| dataSQL.startsWith("update ")
						|| dataSQL.endsWith(" update")
						|| dataSQL.toLowerCase().indexOf("delete ") >= 0
						|| dataSQL.toLowerCase().indexOf("alter ") >= 0) {
					throw new Exception("数据库为只读，无法使用更新等写操作，请确认.");
				} else {
					tableMetaData = DatabaseMetaDataHandler.getSQL(data,
							data.getTaskname(), data.getDatabase(),
							dataSQL);
					if (data.getTablename() == null) {
						data.setTablename("sql");
					}
				}
			}
			TableProperties tablePorperties = null;
			if (data.getTableproperty() == null) {
				data.setTableproperty(new HashSet<TableProperties>());
				if (tableMetaData != null) {
					tableMetaData.setName(data.getTablename());
					for (RivuColumnMetadata colum : tableMetaData
							.getColumnMetadatas()) {
						tablePorperties = new TableProperties(colum.getName(),
								colum.getTypeName(), colum.getColumnSize(),
								data.getTablename());
						tablePorperties.setOrgi(orgi);
						data.getTableproperty().add(tablePorperties);
					}
				} else {
					throw new Exception("导入数据表采集任务失败：" + data.getTablename());
				}
			} 
		} catch (Throwable e) {
			e.printStackTrace();
		}
		return tableMetaData;
	}
	
	private void clearData(TableTask task , JobDetail job){
		OutputTextFormat meta = new OutputTextFormat(job)  ;
		SQLDataValue dataValue = new SQLDataValue();
		dataValue.setSql("DELETE FROM "+task.getTablename()+"_VT WHERE R3_CUBE_DATA_VERSION='"+(Integer.parseInt(this.cube.getDataflag())-1)+"'") ;
		meta.getSql().add(dataValue) ;
		process(meta , job) ;
	}
	
	public void close() throws Exception {
		if(updateDate!=null){
			this.job.setLastdate(updateDate) ;
		}
		if(this.source!=null){
			this.source.close();
		}
		if(this.target!=null){
			this.target.close();
		}
	}

	/* (non-Javadoc)
	 * @see org.jaddy.rivu.resource.Resource#getJob()
	 */
	@Override
	public JobDetail getJob() {
		// TODO Auto-generated method stub
		return this.job;
	}

	/* (non-Javadoc)
	 * @see org.jaddy.rivu.resource.Resource#getText(java.lang.Object)
	 */
	@Override
	public OutputTextFormat getText(OutputTextFormat object) throws Exception {
		// TODO Auto-generated method stub
		return (OutputTextFormat)object;
	}

	/* (non-Javadoc)
	 * @see org.jaddy.rivu.resource.Resource#isAvailable()
	 */
	@Override
	public boolean isAvailable() {
		// TODO Auto-generated method stub
		return true;
	}

	/* (non-Javadoc)
	 * @see org.jaddy.rivu.resource.Resource#next()
	 */
	@Override
	public OutputTextFormat next() throws Exception {
		if(this.job==null)
			return null ;
		return createOutputTextFormat(target);
		
	}
	/**
	 * 获得数据
	 * @param task
	 * @return
	 * @throws SQLException
	 */
	private synchronized OutputTextFormat createOutputTextFormat(TableTask task) throws Exception{
		OutputTextFormat meta = null ;
		if(source.getResultSet()!=null && source.getResultSet().next()){
			meta = new OutputTextFormat(job)  ;
			meta.setJob(job) ;
			meta.setTitle(task.getDatabase().getTaskname()) ;
			meta.setParent(task.getTaskname()) ;
			StringBuffer strb = new StringBuffer() ,field = new StringBuffer()  ,wherecon = new StringBuffer()  , update = new StringBuffer();
			StringBuffer autoid = new StringBuffer();
			Map<String,Object> autoIDMap = new HashMap<String, Object>();
			boolean isAutoID = false ;
			SQLDataValue dataValue = new SQLDataValue();
			for(TableProperties tp : task.getTableproperty()){
				try{
					if(field.length()>0){
						field.append(",") ;
					}
					if(wherecon.length()>0){
						wherecon.append(",") ;
					}
					if(update.length()>0){
						update.append(",") ;
					}
					field.append(tp.getFieldname()) ;
					wherecon.append("?");
					if("R3_CUBE_DATA_ID".equals(tp.getFieldname())){
						isAutoID = true ;
						dataValue.getMetadata().add("R3_CUBE_DATA_ID") ;
					}else if("R3_CUBE_DATA_VERSION".equals(tp.getFieldname())){
						dataValue.getMetadata().add("R3_CUBE_DATA_VERSION") ;
					}else{
						dataValue.setParanum(dataValue.getParanum()+1) ;
						Object obj = null;
						if(tp.getDatatypename().equals("DATE") || tp.getDatatypename().equals("TIMESTAMP")){
							obj = source.getResultSet().getTimestamp(tp.getFieldname()) ;
						}else{
							obj = source.getResultSet().getObject(tp.getFieldname()) ;
						}
						
						String value = "" ;
						if(obj!=null){
							value = obj.toString() ;
						}
						if(tp.getFieldname().startsWith("DIM_")){
//							autoid.append(value) ;
							autoIDMap.put(tp.getFieldname(), value) ;
						}
						if(tp.getFieldname().startsWith("MEA_") && value.length()==0){
							value = "0" ;
						}
						dataValue.getMetadata().add(value) ;
						update.append(tp.getFieldname()).append("=?");
					}
				}catch(Exception ex){
					ex.printStackTrace();
					throw ex;
				}
			}
			String id = RivuTools.md5(autoid.toString()) ;
			
			if(!incremental){//非增量结算模式  加上 版本和 随机数， 增量结算无需加上参数
				if(this.cube!=null && this.cube.getDataflag()!=null){
					autoid.append("_").append(this.cube.getDataflag()) ;
				}
//				autoid.append(java.util.UUID.randomUUID().toString());
			}
			if(autoIDMap.size()>0){
				Iterator<String> fields = autoIDMap.keySet().iterator();
				while(fields.hasNext()){
					String tempField = fields.next() ;
					autoid.append(autoIDMap.get(tempField)) ;
				}
				autoIDMap.clear();
				autoIDMap = null ;
				id = RivuTools.md5(autoid.toString()) ;
			}
			
			if(isAutoID){
				for(int i= 0 ; i<dataValue.getMetadata().size() ; i++){
					if("R3_CUBE_DATA_ID".equals(dataValue.getMetadata().get(i))){
						dataValue.getMetadata().set(i, id) ;
					}
					if("R3_CUBE_DATA_VERSION".equals(dataValue.getMetadata().get(i)) && this.cube != null && cube.getDataflag()!=null){
						dataValue.getMetadata().set(i, cube.getDataflag()) ;
					}
				}
			}
			strb.append("INSERT INTO ").append(task.getTablename().toUpperCase()).append("_VT").append("(");
			strb.append(field.toString()).append(") VALUES(");
			strb.append(wherecon.toString()) ;
			strb.append(")");
			dataValue.setSql(strb.toString()) ;
			
			if(incremental){//增量结算，需要按照原ID删除记录
				strb = new StringBuffer();
				strb.append("DELETE FROM ").append(task.getTablename().toUpperCase()).append("_VT").append(" WHERE R3_CUBE_DATA_ID = ?");
				SQLDataValue deleteValue = new SQLDataValue();
				deleteValue.setParanum(1) ;
				deleteValue.setSql(strb.toString());
				deleteValue.getMetadata().add(id) ;
				meta.getSql().add(deleteValue) ;
			}
			meta.getSql().add(dataValue) ;
		}
		return meta;
	}
	
	/**
	 * 
	 * @param meta
	 * @param tp
	 * @param rsObject
	 * @throws Exception 
	 * @throws ClassNotFoundException 
	 * @throws IllegalAccessException 
	 * @throws InstantiationException 
	 */
	public void process(OutputTextFormat meta , JobDetail job){
		if(target!=null && target.getConn()!=null){
			Statement statement = null ;
			for(SQLDataValue sqlData : meta.getSql()){
				try{
					if(sqlData.getParanum()>0){
						statement = target.getConn().prepareStatement(sqlData.getSql()) ;
						for(int i=1 ; i <= sqlData.getMetadata().size() ; i++){
							((PreparedStatement)statement).setObject(i, sqlData.getMetadata().get(i-1));
						}
						((PreparedStatement)statement).executeUpdate() ;
					}else{
						statement = target.getConn().createStatement();
						statement.execute(sqlData.getSql());
					}
				}catch(Exception ex){
					ex.printStackTrace();
				}finally{
					if(statement!=null){
						try {
							statement.close() ;
						} catch (SQLException e) {
							e.printStackTrace();
						}
					}
				}
			}
		}
	}
	
	@Override
	public void updateTask() {
		if(this.cube!=null && (this.cube.getDataflag()!=null && !this.cube.getDataflag().equals("0"))){
			clearData(target , job);
		}
	}
}
